package kubernetes

import (
	"bytes"
	"context"
	"errors"
	"io"
	"k8s-admin/global"
	"k8s-admin/utils"
	"strconv"
	"time"

	v1 "k8s.io/api/core/v1"
	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type PodesResp struct {
	Items []v1.Pod `json:"items"`
	Total int      `json:"total"`
}

func (c *k8sCluster) GetK8sClusterPod(cid, namespace string) (*PodesResp, error) {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error(err.Error())
		return nil, err

	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)

		defer cancel()
		list, err := cache.CoreV1().Pods(namespace).List(ctx, meta.ListOptions{})
		if err != nil {
			return nil, err
		} else {

			return &PodesResp{
				Items: list.Items,
				Total: len(list.Items),
			}, nil
		}
	}
}

func (c *k8sCluster) GetK8sClusterNamePod(cid, namespace, PodName string) (*v1.Pod, error) {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error(err.Error())
		return nil, err
	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)

		defer cancel()
		get, err := cache.CoreV1().Pods(namespace).Get(ctx, PodName, meta.GetOptions{})
		if err != nil {
			return nil, err
		} else {
			return get, nil
		}
	}
}

func (c *k8sCluster) DeleteK8sClusterPod(cid, namespace, PodName string) error {
	cache, err := utils.GetCache(cid)
	if err != nil {
		global.TPLogger.Error(err.Error())
		return err
	} else {
		var (
			ctx    context.Context
			cancel context.CancelFunc
		)
		ctx, cancel = context.WithTimeout(context.TODO(), time.Second*5)
		defer cancel()
		err := cache.CoreV1().Pods(namespace).Delete(ctx, PodName, meta.DeleteOptions{})
		if err != nil {
			global.TPLogger.Error(err.Error())
			return err
		} else {
			return nil
		}
	}
}

func (c *k8sCluster) GetK8sClusterPodLogs(cid, namespace, PodName, ContainerName string) (string, error) {
	cache, _ := utils.GetCache(cid)
	var line int64
	line = 1000
	podLogOpts := v1.PodLogOptions{
		Container: ContainerName,
		TailLines: &(line), // 临时数据
	}
	podLogsReq := cache.CoreV1().Pods(namespace).GetLogs(PodName, &podLogOpts)
	podLogsStream, err := podLogsReq.Stream(context.TODO())
	if err != nil {
		global.TPLogger.Error(err.Error())

		return "", errors.New("日志查询错误")

	}
	defer podLogsStream.Close()
	// 读取流中的数据，将response body 写入到缓冲区，目的是为了转换成string类型
	buf := new(bytes.Buffer)
	_, err = io.Copy(buf, podLogsStream)
	if err != nil {
		global.TPLogger.Error(err.Error())
		return "", errors.New("日志查询错误")
	}
	return buf.String(), nil
}

// GetK8sClusterPodContainer(cid, namespace, PodName string) ([]map[string]interface{}, error) 获取容器名称
func (c *k8sCluster) GetK8sClusterPodContainer(cid, namespace, PodName string) ([]map[string]interface{}, error) {
	ctx, cancelFunc, cache, err := utils.ClusterClient(cid)
	defer cancelFunc()
	if err != nil {
		global.TPLogger.Error(err.Error())
		return nil, err
	} else {

		list, err := cache.CoreV1().Pods(namespace).Get(ctx, PodName, meta.GetOptions{})
		if err != nil {
			return nil, err
		} else {
			res := make([]map[string]interface{}, 0)
			for index, item := range list.Spec.Containers {
				res = append(res, map[string]interface{}{
					"id":              strconv.Itoa(index + 1), // 这里返回一个ID，用于给前端tabs for遍历使用
					"containers_name": item.Name,
				})
			}
			return res, nil
		}
	}
}
